package io.github.jyrmc.gmcp.plugin

import io.github.jyrmc.gmcp.common.TaskConstant
import io.github.jyrmc.gmcp.extension.MybatisCodegenExtension
import io.github.jyrmc.gmcp.task.GenerateCodeTask
import io.github.jyrmc.gmcp.task.GenerateMarkdownTask
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.ExtensionContainer


class GradleMybatisCodegenPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        project.plugins.apply(GradleMybatisCodegenPlugin::class.java)
        val mybatisCodegenExtension = project.extensions.create<MybatisCodegenExtension>("mybatisCodegenExtension")

        // generate code task
        project.plugins.withType(GradleMybatisCodegenPlugin::class.java).configureEach {
            registerGenerateCodeTask(project, mybatisCodegenExtension)
            registerGenerateMarkdownTask(project, mybatisCodegenExtension)
        }
    }

    /**
     * 注册task
     */
    private fun registerGenerateCodeTask(
        project: Project, extension: MybatisCodegenExtension
    ): Any {
        return project.tasks.register(
            TaskConstant.GEN_CODE_TASK_NAME, GenerateCodeTask::class.java
        ) {
            it.group = TaskConstant.DEFAULT_TASK_GROUP
            it.description = "Generate Mybatis Restful CRUD Base On Mybatis-Plus."
            it.dbType = extension.dbType.get()
            it.url = extension.url.get()
            it.port = extension.port.get()
            it.database = extension.database.get()
            it.userName = extension.userName.get()
            it.password = extension.password.get()
            it.frameworkType = extension.frameworkType.get()
            if (it.frameworkType.isBlank()) {
                it.frameworkType = "mybatisplus"
            }
            it.tablePrefix = extension.tablePrefix.get()
            if (it.tablePrefix.isBlank()) {
                it.tablePrefix = ""
            }
            it.tableNames = extension.tables.get()
            it.ignoreColumns = extension.ignoreColumns.get()
            it.projectPath = extension.projectPath.get()
            it.packageName = extension.packageName.get()
            it.controller = extension.controller.get()
            if (it.controller.isBlank()) {
                it.controller = "controller"
            }
            it.service = extension.service.get()
            if (it.service.isBlank()) {
                it.service = "service"
            }
            it.mapper = extension.mapper.get()
            if (it.mapper.isBlank()) {
                it.mapper = "mapper"
            }
            it.entity = extension.entity.get()
            if (it.entity.isBlank()) {
                it.entity = "entity"
            }
            it.xml = extension.xml.get()
            if (it.xml.isBlank()) {
                it.xml = "mapper"
            }
            it.languageType = extension.languageType.get()
            if (it.languageType.isBlank()) {
                it.languageType = "java"
            }
            it.author = extension.author.get()
            if (it.author.isBlank()) {
                it.author = System.getProperty("user.name")
            }
            it.apiPrefix = extension.apiPrefix.get()
            it.restfulStyle = extension.restfulStyle.get()
            it.swagger = extension.swagger.get()
            it.fileGenStrategy = extension.fileGenStrategy.get()
            if (it.fileGenStrategy.isBlank()) {
                it.fileGenStrategy = "createIfNotExists";
            }
        }
    }

    /**
     * 注册task
     */
    private fun registerGenerateMarkdownTask(
        project: Project, extension: MybatisCodegenExtension
    ): Any {
        return project.tasks.register(
            TaskConstant.GEN_MARKDOWN_TASK_NAME, GenerateMarkdownTask::class.java
        ) {
            it.group = TaskConstant.DEFAULT_TASK_GROUP
            it.description = "Generate Database Table To Markdown Doc."
            it.dbType = extension.dbType.get()
            it.url = extension.url.get()
            it.port = extension.port.get()
            it.database = extension.database.get()
            it.userName = extension.userName.get()
            it.password = extension.password.get()
            it.projectPath = extension.projectPath.get()
        }
    }
}

inline fun <reified T : Any> ExtensionContainer.create(name: String, vararg constructionArguments: Any): T =
    create(name, T::class.java, *constructionArguments)


